package com.chouren.goandroid.ui.view;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver.OnPreDrawListener;

import com.chouren.goandroid.R;
import com.chouren.goandroid.ui.view.model.BarParam;
import com.chouren.goandroid.util.AppUtil;

public class Bar extends View {
	private List<BarParam> dataList;
	private float depth;
	private float marginLeft;
	private float barWidth;
	private float barPiceWidth;
	private float barMarginBottom;
	private float barMarginTop;
	private float maxValue;
	private float tempHeight;
	private Paint keyPaint;
	private Paint valueBarPaint;
	private Paint maxValueBarPaint;
	private int greyColor = 0x5faaaaaa; // 灰色
	private int blueColor = 0xff00ffff; // 蓝色
	private int blackColor = 0xffffffff; // 白色

	public Bar(Context context, List<BarParam> dataList) {
		super(context);
		this.dataList = dataList;
		init();
	}
	
	public Bar(Context context, List<BarParam> dataList, int maxValue) {
		this(context, dataList);
		this.maxValue = maxValue;
	}
	
	private void init() {
		if(dataList == null || dataList.size() < 1) return;
		
		depth = getResources().getDimension(R.dimen.number_depth);
		marginLeft = depth * 5.0f;
		barWidth = depth * 3f;
		barPiceWidth = marginLeft + barWidth;
		barMarginBottom = depth * 2f;
		barMarginTop = depth * 1f;
		
		keyPaint = new Paint();
		keyPaint.setStrokeWidth(depth * 0.5f);
		keyPaint.setTextSize(depth * 1.4f);
		keyPaint.setColor(blackColor);
		keyPaint.setTextAlign(Align.CENTER);
		
		valueBarPaint = new Paint();
		valueBarPaint.setStrokeWidth(depth * 0.1f);
		valueBarPaint.setColor(blueColor);
		valueBarPaint.setStyle(Style.FILL);
		valueBarPaint.setAntiAlias(true);
		
		maxValueBarPaint = new Paint();
		maxValueBarPaint.setStrokeWidth(depth * 0.1f);
		maxValueBarPaint.setColor(greyColor);
		maxValueBarPaint.setStyle(Style.FILL);
		maxValueBarPaint.setAntiAlias(true);
		
		setLayoutParams(new LayoutParams((int)(barPiceWidth * dataList.size()), LayoutParams.MATCH_PARENT));
		
		getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
			@Override
			public boolean onPreDraw() {
				new Thread(new DrawTask()).start();
				getViewTreeObserver().removeOnPreDrawListener(this);
				return false;
			}
		});
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		if(dataList == null || dataList.size() < 1) return;
		
		drawKeys(canvas);
		drawValues(canvas);
	}
	
	private void drawKeys(Canvas canvas) {
		for(int i = 0; i < dataList.size(); i++) {
			String key = dataList.get(i).getKey();
			if(key != null) {
				canvas.drawText(key, marginLeft * i + AppUtil.dip2px(getContext(), depth * 1f), getHeight() - depth * 0.4f, keyPaint);
			}
		}
	}
	
	private void drawValues(Canvas canvas) {
		for(int i = 0; i < dataList.size(); i++) {
			int value = dataList.get(i).getValue();
			
			RectF maxValueRectF = new RectF();
			maxValueRectF.set(marginLeft * i, barMarginTop, barWidth + marginLeft * i, getHeight() - barMarginBottom);
			canvas.drawRoundRect(maxValueRectF, depth * 0.3f, depth * 0.3f, maxValueBarPaint);
			
			RectF valueRectF = new RectF();
			float base = value * 1.0f / maxValue;
			float g = (getHeight() - barMarginBottom) * (1 - base);
			float drawHeight = (tempHeight >= g ? g : tempHeight);
			valueRectF.set(marginLeft * i, drawHeight, barWidth + marginLeft * i, getHeight() - barMarginBottom);
			canvas.drawRoundRect(valueRectF, depth * 0.3f, depth * 0.3f, valueBarPaint);
		}
	}

	public float getMaxValue() {
		return maxValue;
	}

	public void setMaxValue(float maxValue) {
		this.maxValue = maxValue;
	}
	
	class DrawTask implements Runnable {
		private int state;
		public void run() {
			while (true) {
				switch (state) {
				case 0:
					try {
						Thread.sleep(200);
						state = 1;
					} catch (InterruptedException e) {
					}
					break;
				case 1:
					try {
						Thread.sleep(50);
						tempHeight += 2;
						postInvalidate();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					break;
				}
				if (tempHeight >= (getHeight() - barMarginBottom)) return;
			}
		}
	}
	
}
